<template>
  <div ref="chartRef" :style="{ width: props.width, height: props.height }"></div>
</template>

<script setup lang="ts">
import * as echarts from 'echarts/core'
import {
  TitleComponent,
  TooltipComponent,
  ToolboxComponent,
  LegendComponent,
  GridComponent,
} from 'echarts/components'
import { LineChart, BarChart } from 'echarts/charts'
import { CanvasRenderer } from 'echarts/renderers'
import { onMounted, onBeforeUnmount, ref, watch, withDefaults } from 'vue'
import type { EChartsOption } from 'echarts'
import type { EChartsType } from 'echarts/core'

// 注册必须的组件
echarts.use([
  TitleComponent,
  TooltipComponent,
  ToolboxComponent,
  LegendComponent,
  GridComponent,
  LineChart,
  BarChart,
  CanvasRenderer,
])

// props接受自定义属性
const props = withDefaults(
  defineProps<{
    options: EChartsOption
    width?: string
    height?: string
  }>(),
  {
    width: '100%',
    height: '300px',
  },
)

// 挂载的DOM元素
const chartRef = ref<HTMLDivElement | null>(null)
// echarts实例
let chartInstance: EChartsType | null = null

/**
 * 初始化图表
 */
function initChart() {
  if (!chartRef.value) return
  chartInstance = echarts.init(chartRef.value)
  chartInstance.setOption(props.options)
}

// 监听options变化
watch(
  () => props.options,
  (newOpt) => {
    chartInstance?.setOption(newOpt)
  },
)

onMounted(() => {
  initChart()
  window.addEventListener('resize', resizeChart)
})

onBeforeUnmount(() => {
  chartInstance?.dispose()
  window.removeEventListener('resize', resizeChart)
})

/**
 * 窗口大小变化时，重新渲染图表
 */
function resizeChart() {
  chartInstance?.resize()
}
</script>
